package com.ruoyi.back.service.impl

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.date.DateUtil
import cn.hutool.core.util.RandomUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.ruoyi.app.common.*
import com.ruoyi.back.domain.AppUser
import com.ruoyi.back.domain.dto.AppUserDto
import com.ruoyi.back.domain.dto.UserListSearchDto
import com.ruoyi.back.domain.vo.UserDetailVo
import com.ruoyi.back.domain.vo.UserInfo
import com.ruoyi.back.domain.vo.UserListVo
import com.ruoyi.back.enums.UserStatusEnum
import com.ruoyi.back.enums.UserTypeEnum
import com.ruoyi.back.mapper.AppUserMapper
import com.ruoyi.back.service.AppUserService
import com.ruoyi.back.service.UserMemberOrderService
import com.ruoyi.back.service.UserMemberService
import com.ruoyi.common.core.page.TableSupport
import com.ruoyi.common.utils.SecurityUtils
import com.ruoyi.common.utils.bean.BeanUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class AppUserServiceImpl : ServiceImpl<AppUserMapper, AppUser>(), AppUserService {

    @Autowired
    private lateinit var userMemberService: UserMemberService

    @Autowired
    private lateinit var userMemberOrderService: UserMemberOrderService


    override fun operationUser(appUserDto: AppUserDto): AppUser =
        getOne(
            KtQueryWrapper(AppUser::class.java)
                .eq(AppUser::openId, appUserDto.openId)
                .eq(AppUser::loginType, appUserDto.loginType)
        )
            ?.let {
                updateById(it.apply {
                    BeanUtils.copyProperties(appUserDto, this)
                    lastLoginDate = DateUtil.date()
                })
                it
            }
            ?: kotlin.run {

                val appUser = AppUser()
                save(appUser.apply {
                    BeanUtils.copyProperties(appUserDto, this)
                    userId = RandomUtil.randomNumbers(6)
                    registerDate = Date()
                    lastLoginDate = Date()
                })
                appUser
            }

    override fun selectUserByUserId(userId: String): AppUser? =
        getOne(KtQueryWrapper(AppUser::class.java).eq(AppUser::userId, userId))


    override fun selectAppUserList(userListSearchDto: UserListSearchDto): Page<UserListVo> {

        // 查询之前先更新用户的状态类型
        list().parallelStream().forEach {
            updateById(it.apply {
                userType = userMemberService.userMemberType(it.id!!).code
            })
        }

        return TableSupport.buildPageRequest().let { pageDomain ->

            page(
                Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()), KtQueryWrapper(AppUser::class.java)
                    .eq(
                        StrUtil.isNotBlank(userListSearchDto.searchParam),
                        AppUser::username,
                        userListSearchDto.searchParam
                    )
                    .or().eq(
                        StrUtil.isNotBlank(userListSearchDto.searchParam),
                        AppUser::userId,
                        userListSearchDto.searchParam
                    )
                    .eq(StrUtil.isNotBlank(userListSearchDto.source), AppUser::source, userListSearchDto.source)
                    .eq(userListSearchDto.userType != null, AppUser::userType, userListSearchDto.userType)
                    .eq(userListSearchDto.loginType != null, AppUser::loginType, userListSearchDto.loginType)
                    .orderByDesc(AppUser::registerDate)
            )
                .let { appUserPage ->
                    Page<UserListVo>().apply {
                        BeanUtil.copyProperties(appUserPage, this)
                        records = appUserPage.records.takeIf { it.isNotEmpty() }
                            ?.run {
                                map {
                                    UserListVo().apply {
                                        BeanUtil.copyProperties(it, this)
                                        userType = it.userType?.userType()
                                        userTypeCode = it.userType
                                        loginType = it.loginType?.loginType()
                                        memberDate = userMemberService.getUserMemberByUserId(it.id!!)
                                            ?.run { "${beginMemberDate?.format()}至${endMemberDate?.format()}" } ?: "--"
                                        lastLoginDate = it.lastLoginDate?.format()
                                        registerDate = it.registerDate?.format()
                                        totalUseCount = it.receiveCount
                                        useCount = it.useCount
                                    }
                                }
                            }
                    }
                }
        }

    }


    override fun appUserDetail(userId: Long): Data<UserDetailVo> =
        getById(userId)?.let { appUser ->
            Ok("获取用户详情信息成功", UserDetailVo().apply {
                userInfo = appUserInfo(appUser.id!!)
                payRecords = userMemberOrderService.payRecordList(appUser.id!!, TableSupport.buildPageRequest())
            })
        } ?: Fail(201, "当前用户不存在!")

    override fun appUserInfo(userId: Long): UserInfo? =
        getById(userId)?.let {
            UserInfo().apply {
                BeanUtil.copyProperties(it, this)
                userType = it.userType?.userType()
                loginType = it.loginType?.loginType()
                lastLoginDate = it.lastLoginDate?.format()
                registerDate = it.registerDate?.format()
                memberDate = userMemberService.getUserMemberByUserId(it.id!!)
                    ?.run { "${beginMemberDate?.format()}至${endMemberDate?.format()}" } ?: "--"
            }
        }

    override fun freezeAppUser(userId: Long): Data<Boolean> =
        getById(userId)?.run {
            Ok("更新用户状态成功", updateById(apply {
                status = when (status) {
                    UserStatusEnum.NORMAL.code -> UserStatusEnum.FREEZE.code
                    else -> UserStatusEnum.NORMAL.code
                }
            }))
        } ?: Fail(201, "不存在当前用户")

    override fun removeAppUser(userIds: String): Data<Boolean> =
        Ok("批量移除成功", removeByIds(userIds.split(",")))

    override fun cancelMember(userId: Long): Data<Boolean> =
        userMemberService.userMemberType(userId).run {
            (this == UserTypeEnum.EXPIRE_MEMBER || this == UserTypeEnum.NORMAL).takeIf { true }
                ?.run { Fail(201, "当前用户已经不是正式会员") }
                ?: kotlin.run {
                    Ok("移除用户会员成功", userMemberService.removeUserMember(userId))
                }
        }
}